package org.rxc.base.service.impl;

import org.rxc.auth.domain.Permission;
import org.rxc.auth.mapper.PermissionMapper;
import org.rxc.base.annotation.PlatformAnnotation;
import org.rxc.base.service.IAutoScanPermissionService;
import org.rxc.base.utils.ClassUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
@Service
public class AutoScanPermissionServiceImpl implements IAutoScanPermissionService {
    @Value("${scan.paths}")
    private String paths;
    @Value("${scan.tages}")
    private boolean tages;

    @Autowired
    private PermissionMapper permissionMapper;
    @Override
    public void scan() {
        //检查是否需要扫描权限配置
        if (!tages) return;
        List<Class> allClassName = ClassUtils.getAllClassName(paths);
        //扫描后存放的父级资源
        List<Permission> permissions = new ArrayList<>();
        for (Class controllerClass : allClassName) {
            //获取controller上的注解
            PlatformAnnotation annotation = (PlatformAnnotation) controllerClass.getAnnotation(PlatformAnnotation.class);
            //有可能获取不到annotation为null 不做权限控制
            if (annotation == null) continue;
            Permission parent = new Permission();
            //数据组装
            parent.setName(annotation.name());
            parent.setDescs(annotation.desc());
            RequestMapping requestMapping = (RequestMapping) controllerClass.getAnnotation(RequestMapping.class);
            parent.setUrl(requestMapping.value()[0]);
            parent.setSn(controllerClass.getSimpleName());
            permissions.add(parent);
            //检查父级菜单数据库是否有数据  没有就添加 否则就修改
            Permission permission = permissionMapper.queryBySn(parent.getSn());
            if (permission != null){
                parent.setId(permission.getId());
                permissionMapper.update(parent);
            }else {
                permissionMapper.save(parent);
            }
            //子级资源菜单
            //获取controller里的所有方法
            Method[] methods = controllerClass.getMethods();
            for (Method method : methods) {
                //获取添加了PlatformAnnotation注解的方法 并做权限控制
                PlatformAnnotation annotationMethod = method.getAnnotation(PlatformAnnotation.class);
                if (annotationMethod == null)continue;
                Permission child =  new Permission();
                child.setName(annotationMethod.name());
                child.setDescs(annotationMethod.desc());
                //类名:方法名
                child.setSn(parent.getSn()+":"+method.getName());
                child.setParentId(parent.getId());

                String childUrl = getChildUrl(method);
                child.setUrl(parent.getUrl()+childUrl);
                Permission childInDb = permissionMapper.queryBySn(child.getSn());
                if (childInDb != null){
                    child.setId(childInDb.getId());
                    permissionMapper.update(child);
                }else {
                    permissionMapper.save(child);
                }
            }
        }
    }
    private String getChildUrl(Method method){
        RequestMapping annotation = method.getAnnotation(RequestMapping.class);
        if (annotation!=null){
            return annotation.value().length>0?annotation.value()[0]:"";
        }
        GetMapping getMapping = method.getAnnotation(GetMapping.class);
        if (getMapping!=null){
            return getMapping.value().length>0?getMapping.value()[0]:"";
        }
        PutMapping putMapping = method.getAnnotation(PutMapping.class);
        if (putMapping!=null){
            return putMapping.value().length>0?putMapping.value()[0]:"";
        }
        DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
        if (deleteMapping!=null){
            return deleteMapping.value().length>0?deleteMapping.value()[0]:"";
        }
        PostMapping postMapping = method.getAnnotation(PostMapping.class);
        if (postMapping!=null){
            return postMapping.value().length>0?postMapping.value()[0]:"";
        }
        PatchMapping patchMapping = method.getAnnotation(PatchMapping.class);
        if (patchMapping!=null){
            return patchMapping.value().length>0?patchMapping.value()[0]:"";
        }
        return "";
    }
}
